﻿using System;
using System.IO;
using System.Reflection;
using System.Windows;
using Prism.Ioc;
using Prism.Mvvm;
using Prism.Services.Dialogs;
using Prism.Unity;
using SqlSugar.IOC;
using WPFNote.Utilities;
using WPFNote.Utilities.Common;
using WPFNote.ViewModels;

namespace WPFNote
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : PrismApplication
    {
        protected override Window CreateShell()
        {
            var mainWindow = Container.Resolve<Views.MainWindow>();
            MainWindow = mainWindow;
            return mainWindow;
        }

        protected override void OnInitialized()
        {
            if (ClientUserInfo())
            {
                if (App.Current.MainWindow is { DataContext: IConfigureService service })
                {
                    // 加载配置
                    LoadConfig();
                    service.Configure();
                }

                base.OnInitialized();
                return;
            }

            var dialog = Container.Resolve<IDialogService>();
            dialog.ShowDialog("Login", callback =>
            {
                if (callback.Result != ButtonResult.OK)
                {
                    Environment.Exit(0);
                    return;
                }

                if (App.Current.MainWindow is { DataContext: IConfigureService service })
                {
                    // 加载配置
                    LoadConfig();
                    service.Configure();
                }
                base.OnInitialized();
            });
        }

        /// <summary>
        /// 配置View与ViewModel映射关系，用于自动绑定ViewModel
        /// </summary>
        protected override void ConfigureViewModelLocator()
        {
            base.ConfigureViewModelLocator();
            // 定义view和viewmodel的映射关系
            ViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver((viewType) =>
            {
                if (viewType.FullName != null)
                {
                    var viewName = viewType.FullName.Replace(".Views.", ".ViewModels.") + "ViewModel";
                    var viewAssemblyName = viewType.GetTypeInfo().Assembly.FullName?.Replace(".Views", ".ViewModels");
                    var viewModelName = $"{viewName}, {viewAssemblyName}";
                    var obj = Type.GetType(viewModelName);
                    return obj;
                }

                return null;
            });
        }

        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            // 项目启动的时候，注入SqlSugar
            SugarIocServices.AddSqlSugar(new IocConfig()
            {
                ConnectionString = $@"DataSource={AppSession.DbPath}",
                DbType = IocDbType.Sqlite,
                IsAutoCloseConnection = true //自动释放
            });

            containerRegistry.Register<IDialogHostService, DialogHostService>();

            containerRegistry.Register<Repository.IDal.ICategory, Repository.Category>();
            containerRegistry.Register<Services.IDal.ICategory, Services.Category>();

            containerRegistry.Register<Repository.IDal.INote, Repository.Note>();
            containerRegistry.Register<Services.IDal.INote, Services.Note>();

            containerRegistry.Register<Repository.IDal.IUsers, Repository.Users>();
            containerRegistry.Register<Services.IDal.IUsers, Services.Users>();

            containerRegistry.Register<Repository.IDal.ILogs, Repository.Logs>();
            containerRegistry.Register<Services.IDal.ILogs, Services.Logs>();

            containerRegistry.RegisterDialog<Views.Login, LoginViewModel>();
            containerRegistry.RegisterForNavigation<Views.Index, IndexViewModel>("Index");
            containerRegistry.RegisterForNavigation<Views.NoteEdit, NoteEditViewModel>("NoteEdit");
            containerRegistry.RegisterForNavigation<Views.NoteAdd, NoteAddViewModel>("NoteAdd");
            containerRegistry.RegisterForNavigation<Views.Msg, MsgViewModel>("Msg");
            containerRegistry.RegisterDialog<Views.Config, ConfigViewModel>();
        }

        private bool ClientUserInfo()
        {
            try
            {
                if (File.Exists(AppSession.UserInfoPath))
                {
                    AppSession.UserInfo =
                        Newtonsoft.Json.JsonConvert.DeserializeObject<Models.Users>(
                            EncryptionHelper.DecodeBase64(new BinFileHelper().Read(AppSession.UserInfoPath)));
                    return AppSession.UserInfo != null;
                }

                return false;
            }
            catch
            {
                return false;
            }
        }
        
        private void LoadConfig()
        {
            if (!File.Exists(AppSession.ConfigPath)) return;
            var json = EncryptionHelper.DecodeBase64(new BinFileHelper().Read(AppSession.ConfigPath));
            Config.Init().JsonParse(json);
        }
    }
}